package com.group9.handinhand.dao;

import java.util.List;

import org.springframework.stereotype.Repository;

import com.group9.handinhand.dao.model.Offer;
import com.group9.handinhand.dao.model.OfferPost;
import com.group9.handinhand.dao.model.OfferResponse;
import com.group9.handinhand.dao.model.Request;
import com.group9.handinhand.dao.model.User;
import com.group9.handinhand.service.so.UserTagSO;
/**
 * Class for Offer Dao
 *
 */
@Repository
public class OfferDao extends BaseDaoImpl {

	public Offer saveOffer(Offer offer) {
		save(offer);
		return offer;
	}
	/**
	 * finds offer by offer id
	 * @param offerId
	 * @return
	 */
	public Offer findOfferById(Long offerId) {
		return (Offer)findById(Offer.class, offerId);
	}
	/**
	 * finds offer by tag
	 * @param tag
	 * @return
	 */
	public List<Offer> findOffersByTag(UserTagSO tag) {
		String queryString = "Select distinct (ot.offer) from OfferTag ot inner join ot.tag es where es.id =:tagId";
		return executeQueryString(queryString, "tagId", tag.getTag().getId());
	}
	/**
	 * finds offer by tag name
	 * @param keyword
	 * @return
	 */
	public List<Offer> findOffersByTagName(String keyword) {
		String queryString = "Select distinct (ot.offer) from OfferTag ot inner join ot.tag es where es.tagName =:keyWord";
		return executeQueryString(queryString, "keyWord", keyword);
	}
	/**
	 * finds offer by its name
	 * @param keyword
	 * @return
	 */
	public List<Offer> findOffersByName (String keyword) {
		String queryString = "from Offer ff where str(ff.name) like :keyWord";
		return executeQueryString(queryString, "keyWord", "%"+keyword+"%");
	}
	/**
	 * finds the offer that is responded by a user using user id
	 * @param user
	 * @return
	 */
	public List<Offer> findRespondedOffersByUser(User user) {
		String queryString = "Select distinct (ea.offer) from OfferResponse ea inner join ea.user es where es.id =:userId";
		return executeQueryString(queryString, "userId", user.getId());
	}
	/**
	 * finds moderated offers by a user
	 * @param user
	 * @return
	 */
	public List<Offer> findModeratedOffersByUser(User user) {
		String queryString = "Select distinct o from Offer o inner join o.moderators om where om.id =:userId";
		return executeQueryString(queryString, "userId", user.getId());
	}
	/**
	 * saves the post of offer
	 * @param offerPost
	 * @return
	 */
	public OfferPost saveOfferPost(OfferPost offerPost) {
		save(offerPost);
		return offerPost;
	}
	/** 
	 * saves offer response
	 * @param offerResponse
	 * @return
	 */
	public OfferResponse saveOfferResponse(OfferResponse offerResponse) {
		save(offerResponse);
		return offerResponse;
	}
	/**
	 * finds requests responses
	 * @param userId
	 * @param offerId
	 * @return
	 */
	public List<OfferResponse> findRequestResponsesByUserIdAndOfferId(Long userId, Long offerId) {
		String queryString = "from OfferResponse as ofr where ofr.user.id =:userId and ofr.offer.id =:offerId";
		return executeQueryString(queryString, new String[]{"userId" , "offerId"}, new Object[]{userId,offerId});
	}
	/**
	 * finds moderators by offer id
	 * @param offerId
	 * @return
	 */
	public List<User> findModeratorsByOfferId(Long offerId) {
		String queryString = "Select om from Offer o inner join o.moderators om where o.id =:offerId";
		return executeQueryString(queryString, "offerId", offerId);
	}

	public Offer updateOffer(Offer offer) {
		update(offer);
		return offer;
	}
	/**
	 * find moderated offer using offer id and user id.
	 * @param offerId
	 * @param userId
	 * @return
	 */
	public Offer findModeratedOfferByOfferIdAndUserId(Long offerId, Long userId) {
		String queryString = "Select o from Offer o inner join o.moderators om where om.id =:userId and o.id =:offerId";
		return executeQueryStringForObject(queryString, new String[]{"offerId" , "userId"}, new Object[]{offerId,userId});
	}

}
